'''
Created on Nov 9, 2009

@author: aamn
'''

from ConfigParser import  SafeConfigParser

class Section:
    def __init__(self, name, parser):
        self.__dict__['name'] = name
        self.__dict__['parser'] = parser

    def get(self, name, parsetype):
        ''' allow individual section element lookup with special parsers'''
        parser = self.parser
        if parsetype is int:
            return parser.getint(self.name, name)
        elif parsetype is bool:
            return parser.getboolean(self.name, name)
        elif parsetype is float:
            return parser.getfloat(self.name, name)
        elif parsetype is str:
            return parser.get(self.name, name)
        else:
            return parser.get(self.name, name)

    def __setattr__(self, attr, value):
        self.__dict__[attr] = str(value)
        self.parser.set(self.name, attr, str(value))

    def __call__(self):
        '''DM.Section() returns a dictionary of the section elements'''
        parser = self.parser
        return dict([(o, parser.get(self.name, o))
                    for o in parser.options(self.name)])

    def __str__ (self):
        '''pretty print the config elements'''
        p = self.parser
        result = []
        result.append('[%s]' % self.name)
        for o in p.options(self.name):
                result.append('%s=%s' % (o, p.get(self.name, o)))
        return '\n'.join(result)

    def __repr__(self): return self.__str__()


class Configuration(object):
    def __init__(self, fileName):
        self.__parser = SafeConfigParser()
        self.__parser.optionxform = lambda x: x
        self.__parser.read(fileName)
        self.fileName = fileName
        for section in self.__parser.sections():
            setattr(self, section, Section(section, self.__parser))
            for option in self.__parser.options(section):
                setattr(getattr(self, section), option,
                        self.__parser.get(section, option))

    def __getattr__(self, attr):
        if attr not in ['trait_names', '__methods__', '__members__', '_getAttributeNames']:
            self.__parser.add_section(attr)
            setattr(self, attr, Section(attr, self.__parser))
            return getattr(self, attr)


    def __call__(self):
        '''DM() returns a dictionary model of the model'''
        parser = self.__parser
        return dict([
                     (foo, dict([(o, parser.get(foo, o))
                                 for o in parser.options(foo)]))
                     for foo in parser.sections()
                     ])

    def __str__ (self):
        '''pretty print the config elements'''
        p = self.__parser
        result = []
        result.append('<Configuration from %s>' % self.fileName)
        for s in p.sections():
            result.append('[%s]' % s)
            for o in p.options(s):
                result.append('%s=%s' % (o, p.get(s, o)))
        return '\n'.join(result)

    def __repr__(self): return self.__str__()

    def save(self):
        f = open(self.fileName, 'w')
        self.__parser.write(f)
        f.close()
